<template>
  <div class="vuefinder__explorer__container">
    <a-upload-dragger
      multiple
      :disabled="
        app.requestParams.disabled ||
        !(isManager || app.fs.data.options.permissions?.addfile)
      "
      :openFileDialogOnClick="false"
      :showUploadList="false"
      :before-upload="beforeUpload"
    >
      <div class="vuefinder__explorer__drag-item">
        <DragItem ref="dragImage" :count="ds.getCount()" />
      </div>
      <div
        :ref="ds.scrollBarContainer"
        class="vf-explorer-scrollbar-container vuefinder__explorer__scrollbar-container"
        :class="[
          { 'grid-view': app.view === 'grid' },
          { 'search-active': searchQuery.length },
        ]"
      >
        <div :ref="ds.scrollBar" class="vuefinder__explorer__scrollbar"></div>
      </div>

      <div
        :ref="ds.area"
        class="vuefinder__explorer__selector-area vf-explorer-scrollbar vf-selector-area min-h-32 h-[calc(100%_-_64px)]"
        @contextmenu.self.prevent="
          app.emitter.emit('vf-contextmenu-show', {
            event: $event,
            items: ds.getSelected(),
          })
        "
      >
        <div
          class="vuefinder__linear-loader absolute"
          v-if="app.loadingIndicator === 'linear' && app.fs.loading"
        ></div>
        <!-- Search View -->
        <div
          v-if="!getItems().length"
          class="w-full flex flex-col justify-center items-center mt-[30vh]"
        >
          <a-image
            class="w-[300px]"
            mode="scaleToFill"
            :preview="false"
            :src="emptyPath"
          />
          <span class="my-[10px] text-neutral-6">文件夹空空如也</span>
          <span
            class="mb-6 text-neutral-6"
            v-if="
              !app.requestParams.disabled &&
              (isManager || app.fs.data.options.permissions?.addfile)
            "
            >文件拖拽至此区域上传</span
          >
          <div
            v-if="
              !app.requestParams.disabled &&
              (isManager || app.fs.data.options.permissions?.addfolder)
            "
            class="flex items-center cursor-pointer px-[15px] py-[7px] border border-solid rounded-xs border-neutral-5 hover:border-primary-6 hover:text-primary-6"
            @click="app.modal.open(ModalNewFolder, { items: ds.getSelected() })"
          >
            <span class="iconfont icon-TX-folder-add pr-1"></span>
            <span>新建文件夹</span>
          </div>
        </div>
        <template v-else>
          <div v-if="app.view === 'list'" class="list-box h-full w-full">
            <a-table
              class="ant-table-striped h-full"
              rowKey="id"
              :pagination="false"
              :columns="columns"
              :data-source="getItems(false)"
              :row-class-name="
                (_record, index) => (index % 2 === 1 ? 'table-striped' : null)
              "
              :customRow="customRow"
            >
              <template #bodyCell="{ column, record, index }">
                <template v-if="column.dataIndex === 'index'">
                  {{ index + 1 }}
                </template>
                <template v-if="column.dataIndex === 'preview'">
                  <a-image
                    v-if="isImagePath(record.path)"
                    class="vuefinder__explorer__item-thumbnailimg lazy vuefinder__item-icon--small"
                    :src="record.url"
                  />
                  <ItemIcon
                    :type="record.type"
                    :path="record.path"
                    small
                    v-else
                  />
                </template>
              </template>
            </a-table>
          </div>
          <template v-else-if="app.view === 'grid'">
            <a-checkbox-group
              v-if="showMultiple"
              v-model:value="selectedCustomValues"
              class="flex"
            >
              <a-checkbox
                v-for="(item, index) in getItems(false)"
                :value="item.basename"
                :key="index"
                class="block h-max p-[8px] rounded-lg hover:bg-primary-2"
              >
                <item
                  :item="item"
                  :index="index"
                  :dragImage="dragImage"
                  class="vf-item vf-item-grid"
                  draggable="false"
                >
                  <div>
                    <div class="vuefinder__explorer__item-grid-content">
                      <img
                        v-if="isImagePath(item.path)"
                        class="vuefinder__explorer__item-thumbnailimg lazy"
                        :src="item.url"
                        :data-src="item.url"
                        :alt="item.basename"
                        :key="item.path"
                      />
                      <ItemIcon :type="item.type" :path="item.path" v-else />
                    </div>
                    <span class="vuefinder__explorer__item-title break-all">{{
                      title_shorten(item.basename)
                    }}</span>
                  </div>
                </item>
              </a-checkbox>
            </a-checkbox-group>
            <template v-else>
              <item
                v-for="(item, index) in getItems(false)"
                :item="item"
                :key="index"
                :index="index"
                :dragImage="dragImage"
                class="vf-item vf-item-grid"
                draggable="false"
              >
                <div>
                  <div class="vuefinder__explorer__item-grid-content">
                    <img
                      v-if="isImagePath(item.path)"
                      class="vuefinder__explorer__item-thumbnailimg lazy"
                      :src="item.url"
                      :data-src="item.url"
                      :alt="item.basename"
                      :key="item.path"
                    />
                    <ItemIcon :type="item.type" :path="item.path" v-else />
                  </div>
                  <span class="vuefinder__explorer__item-title break-all">{{
                    title_shorten(item.basename)
                  }}</span>
                </div>
              </item>
            </template>
          </template>
        </template>
      </div>

      <Toast />
    </a-upload-dragger>
    <a-image
      :style="{ display: 'none' }"
      :preview="{
        visible,
        onVisibleChange: setVisible,
      }"
      :src="previewSrc"
    />
  </div>
</template>

<script setup>
import FolderSVG from './icons/folder.svg'
import FileSVG from './icons/file.svg'
import PdfSVG from './icons/pdf.svg'
import {
  inject,
  onBeforeUnmount,
  onMounted,
  onUpdated,
  reactive,
  ref,
  toRefs,
  watch,
} from 'vue'
import { isImagePath, convertBytes, getFileSuffix } from '../utils/common.js'
import ModalPreview from "./modals/ModalPreview.vue";
import ModalNewFolder from './modals/ModalNewFolder.vue'
import datetimestring from '../utils/datetimestring.js'
import title_shorten from '../utils/title_shorten.js'
import Toast from './Toast.vue'
import LazyLoad from 'vanilla-lazyload'
import SortIcon from './SortIcon.vue'
import ItemIcon from './ItemIcon.vue'
import DragItem from './DragItem.vue'
import Item from './Item.vue'
const emptyPath = new URL('../assets/images/empty.svg', import.meta.url).href

const app = inject('ServiceContainer')
const { t } = app.i18n

const props = defineProps({
  isManager: {
    type: Boolean,
    default: false,
  },
})
const visible = ref(false)
const previewSrc = ref('')
const setVisible = (value) => {
  visible.value = value
}
const { isManager } = toRefs(props)
const showMultiple = ref(false)
const selectedCustomValues = ref([])
watch(selectedCustomValues, (newValue, oldValue) => {
  console.log('newValue', newValue)
})

const columns = [
  {
    title: '序',
    scopedSlots: { customRender: 'index' },
    dataIndex: 'index',
    key: 'index',
  },
  {
    title: '预览',
    dataIndex: 'preview',
    key: 'preview',
    resizable: false,
  },
  {
    title: '文件名称',
    dataIndex: 'basename',
    key: 'basename',
    width: '55%',
    ellipsis: true,
    resizable: true,
  },
  {
    title: '文件类型',
    dataIndex: 'extention',
    key: 'extention',
    ellipsis: true,
    resizable: true,
    customRender: ({ text, record }) => {
      return record.type === 'dir' ? '文件夹' : text
    },
  },
  {
    title: '文件大小',
    dataIndex: 'size',
    key: 'size',
    ellipsis: true,
    resizable: true,
    customRender: ({ text }) => {
      return text ? convertBytes(text) : ''
    },
  },
  {
    title: '上传人',
    dataIndex: 'employee_name',
    key: 'employee_name',
    ellipsis: true,
    resizable: true,
  },
  {
    title: '上传时间',
    dataIndex: 'created_at',
    key: 'created_at',
    ellipsis: true,
    resizable: true,
  },
]

const customRow = (record) => {
  return {
    onDblclick: () => {
      if (record.type == 'dir') {
        app.emitter.emit('vf-fetch', {
          params: { dir: record.path, dir_id: record.id },
        })
      } else if (isImagePath(record.path)) {
        previewSrc.value = record.url
        setVisible(true)
      } else if (['.pdf', '.mp4', '.doc', '.docx', '.pptx', '.ppt', '.xlsx'].some(n => record.basename.endsWith(n))) {
        app.modal.open(ModalPreview, {adapter: app.fs.adapter, item: record })
      }else {
        message.warn('当前文件类型暂不支持预览')
      }
    },
    onContextmenu: (event) => {
      event.preventDefault()
      app.emitter.emit('vf-contextmenu-show', {
        event,
        items: ds.getSelected(),
        target: record,
      })
    },
  }
}

const ext = (item) => item?.substring(0, 3)
const dragImage = ref(null)

const searchQuery = ref('')
const ds = app.dragSelect

/** @type {import('vanilla-lazyload').ILazyLoadInstance} */
let vfLazyLoad

app.emitter.on('vf-fullscreen-toggle', () => {
  ds.area.value.style.height = null
})

app.emitter.on('vf-search-query', ({ newQuery }) => {
  searchQuery.value = newQuery

  if (newQuery) {
    app.emitter.emit('vf-fetch-search', {
      params: {
        dir: app.fs.data.dirname,
        dir_id: app.fs.data.dir_id,
        searchkey: newQuery,
      },
      // onSuccess: (data) => {
      //   if (!data.files.length) {
      //     app.emitter.emit('vf-toast-push', {
      //       label: t('No search result found.'),
      //     })
      //   }
      // },
    })
  } else {
    app.fs.fullPathList = []
    app.emitter.emit('vf-fetch', { params: { dir: 'local://', dir_id: 0 } })
  }
})

const sort = reactive({ active: false, column: '', order: '' })

const getItems = (sorted = true) => {
  let files = [...app.fs.data.files],
    column = sort.column,
    order = sort.order === 'asc' ? 1 : -1

  if (!sorted) {
    return files
  }

  const compare = (a, b) => {
    if (typeof a === 'string' && typeof b === 'string') {
      return a.toLowerCase().localeCompare(b.toLowerCase())
    }
    if (a < b) return -1
    if (a > b) return 1
    return 0
  }

  if (sort.active) {
    files = files.slice().sort((a, b) => compare(a[column], b[column]) * order)
  }
  return files
}

const sortBy = (column) => {
  if (sort.active && sort.column === column) {
    sort.active = sort.order === 'asc'
    sort.column = column
    sort.order = 'desc'
  } else {
    sort.active = true
    sort.column = column
    sort.order = 'asc'
  }
}

const beforeUpload = (file) => {
  handleUpload(file)
  return false
}

const handleUpload = (file) => {
  app.emitter.emit('vf-fetch-upload', {
    params: {
      file,
    },
    body: {
      title: file.name,
      dir: app.fs.data.dirname,
      dir_id: app.fs.data.dir_id,
      size: file.size,
      extention: getFileSuffix(file.type)['subcategory'],
    },
    onSuccess: () => {
      app.emitter.emit('vf-fetch', {
        params: { dir: app.fs.data.dirname, dir_id: app.fs.data.dir_id },
      })
    },
    onError: (e) => {
      message.error(t(e.message))
    },
  })
}

onMounted(() => {
  vfLazyLoad = new LazyLoad(ds.area.value)
})

onUpdated(() => {
  vfLazyLoad.update()
})

onBeforeUnmount(() => {
  vfLazyLoad.destroy()
})
</script>
<style scoped>
[data-doc-theme='light'] .ant-table-striped :deep(.table-striped) td {
  background-color: #fafafa;
}
[data-doc-theme='dark'] .ant-table-striped :deep(.table-striped) td {
  background-color: rgb(29, 29, 29);
}
</style>
